//! # RustCloud Admin Framework
//!
//! 统一的管理和运维框架，提供以下功能：
//! - RESTful 管理 API
//! - Web 管理界面
//! - 系统信息收集
//! - 配置热更新
//! - 操作审计
//! - 诊断和调试工具

// 公共模块
pub mod api;
pub mod web_ui;
pub mod system_info;
pub mod config_manager;
pub mod audit;
pub mod diagnostics;
pub mod auth;
pub mod service_discovery;

// 错误处理
pub mod error;
pub use error::*;

// 预导入模块
pub mod prelude {
    pub use crate::api::*;
    pub use crate::system_info::*;
    pub use crate::config_manager::*;
    pub use crate::audit::*;
    pub use crate::auth::*;
    pub use crate::service_discovery::*;
    pub use crate::error::*;
}

use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::RwLock;

use rustcloud_core::{ServiceError, ServiceResult, ServiceRegistry, ServiceInstance};
use std::time::Duration;

/// 管理框架错误类型
#[derive(Debug, Clone, thiserror::Error)]
pub enum AdminError {
    #[error("API错误: {0}")]
    ApiError(String),
    
    #[error("认证错误: {0}")]
    AuthError(String),
    
    #[error("配置错误: {0}")]
    ConfigError(String),
    
    #[error("系统信息错误: {0}")]
    SystemInfoError(String),
    
    #[error("审计错误: {0}")]
    AuditError(String),
    
    #[error("诊断错误: {0}")]
    DiagnosticsError(String),
    
    #[error("内部错误: {0}")]
    InternalError(String),
}

impl AdminError {
    pub fn api_error(msg: &str) -> Self {
        Self::ApiError(msg.to_string())
    }
    
    pub fn auth_error(msg: &str) -> Self {
        Self::AuthError(msg.to_string())
    }
    
    pub fn config_error(msg: &str) -> Self {
        Self::ConfigError(msg.to_string())
    }
    
    pub fn system_info_error(msg: &str) -> Self {
        Self::SystemInfoError(msg.to_string())
    }
    
    pub fn audit_error(msg: &str) -> Self {
        Self::AuditError(msg.to_string())
    }
    
    pub fn diagnostics_error(msg: &str) -> Self {
        Self::DiagnosticsError(msg.to_string())
    }
    
    pub fn internal_error(msg: &str) -> Self {
        Self::InternalError(msg.to_string())
    }
}

pub type AdminResult<T> = Result<T, AdminError>;

/// 管理组件接口
#[async_trait]
pub trait AdminComponent: Send + Sync {
    /// 组件名称
    fn name(&self) -> &str;
    
    /// 组件版本
    fn version(&self) -> &str;
    
    /// 启动组件
    async fn start(&self) -> AdminResult<()>;
    
    /// 停止组件
    async fn stop(&self) -> AdminResult<()>;
    
    /// 获取组件状态
    async fn status(&self) -> AdminResult<ComponentStatus>;
    
    /// 获取组件配置
    async fn get_config(&self) -> AdminResult<serde_json::Value>;
    
    /// 更新组件配置
    async fn update_config(&self, config: serde_json::Value) -> AdminResult<()>;
}

/// 组件状态
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum ComponentStatus {
    /// 运行中
    Running,
    /// 已停止
    Stopped,
    /// 启动中
    Starting,
    /// 停止中
    Stopping,
    /// 错误
    Error(String),
}

/// 管理框架配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AdminConfig {
    /// HTTP服务器配置
    pub server: ServerConfig,
    /// 身份验证配置
    pub auth: AuthConfig,
    /// 审计配置
    pub audit: AuditConfig,
    /// 诊断配置
    pub diagnostics: DiagnosticsConfig,
}

/// HTTP服务器配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServerConfig {
    /// 监听地址
    pub host: String,
    /// 监听端口
    pub port: u16,
    /// 是否启用TLS
    pub tls_enabled: bool,
    /// TLS证书文件路径
    pub tls_cert_path: Option<String>,
    /// TLS私钥文件路径
    pub tls_key_path: Option<String>,
    /// 请求超时（秒）
    pub request_timeout_secs: u64,
    /// 最大请求大小（字节）
    pub max_request_size_bytes: usize,
}

/// 身份验证配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthConfig {
    /// 是否启用认证
    pub enabled: bool,
    /// JWT密钥
    pub jwt_secret: String,
    /// Token过期时间（秒）
    pub token_expiry_secs: u64,
    /// 管理员用户配置
    pub admin_users: Vec<AdminUser>,
}

/// 管理员用户
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AdminUser {
    /// 用户名
    pub username: String,
    /// 密码哈希
    pub password_hash: String,
    /// 角色
    pub roles: Vec<String>,
    /// 是否启用
    pub enabled: bool,
}

/// 审计配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuditConfig {
    /// 是否启用审计
    pub enabled: bool,
    /// 审计日志路径
    pub log_path: String,
    /// 日志保留天数
    pub retention_days: u32,
    /// 最大日志文件大小（MB）
    pub max_file_size_mb: u64,
}

/// 诊断配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DiagnosticsConfig {
    /// 是否启用诊断
    pub enabled: bool,
    /// 诊断信息收集间隔（秒）
    pub collection_interval_secs: u64,
    /// 历史数据保留期（小时）
    pub retention_hours: u64,
}

impl Default for AdminConfig {
    fn default() -> Self {
        Self {
            server: ServerConfig {
                host: "0.0.0.0".to_string(),
                port: 8080,
                tls_enabled: false,
                tls_cert_path: None,
                tls_key_path: None,
                request_timeout_secs: 30,
                max_request_size_bytes: 10 * 1024 * 1024, // 10MB
            },
            auth: AuthConfig {
                enabled: true,
                jwt_secret: "change-me-in-production".to_string(),
                token_expiry_secs: 3600, // 1小时
                admin_users: vec![
                    AdminUser {
                        username: "admin".to_string(),
                        password_hash: "$argon2id$v=19$m=4096,t=3,p=1$c2FsdA$hash".to_string(),
                        roles: vec!["admin".to_string()],
                        enabled: true,
                    }
                ],
            },
            audit: AuditConfig {
                enabled: true,
                log_path: "./logs/admin_audit.log".to_string(),
                retention_days: 90,
                max_file_size_mb: 100,
            },
            diagnostics: DiagnosticsConfig {
                enabled: true,
                collection_interval_secs: 60,
                retention_hours: 72,
            },
        }
    }
}

/// 管理框架主结构
pub struct AdminFramework {
    config: AdminConfig,
    components: Arc<RwLock<HashMap<String, Box<dyn AdminComponent>>>>,
    server_handle: Option<tokio::task::JoinHandle<()>>,
}

impl AdminFramework {
    /// 创建新的管理框架实例
    pub fn new(config: AdminConfig) -> Self {
        Self {
            config,
            components: Arc::new(RwLock::new(HashMap::new())),
            server_handle: None,
        }
    }

    /// 注册组件
    pub async fn register_component(&self, component: Box<dyn AdminComponent>) -> AdminResult<()> {
        let name = component.name().to_string();
        let mut components = self.components.write().await;
        
        if components.contains_key(&name) {
            return Err(AdminError::api_error(&format!("组件已存在: {}", name)));
        }
        
        components.insert(name, component);
        Ok(())
    }

    /// 获取组件
    pub async fn get_component(&self, name: &str) -> Option<Box<dyn AdminComponent>> {
        let components = self.components.read().await;
        // 注意：这里由于trait object的限制，我们无法真正克隆
        // 在实际实现中，需要使用Arc<dyn AdminComponent>或其他方式
        None
    }

    /// 列出所有组件
    pub async fn list_components(&self) -> Vec<String> {
        let components = self.components.read().await;
        components.keys().cloned().collect()
    }

    /// 启动管理框架
    pub async fn start(&mut self) -> AdminResult<()> {
        tracing::info!("启动RustCloud管理框架");
        
        // 启动所有注册的组件
        {
            let components = self.components.read().await;
            for (name, component) in components.iter() {
                match component.start().await {
                    Ok(_) => tracing::info!("组件启动成功: {}", name),
                    Err(e) => tracing::error!("组件启动失败: {} - {}", name, e),
                }
            }
        }

        // 启动HTTP服务器
        self.start_server().await?;
        
        Ok(())
    }

    /// 停止管理框架
    pub async fn stop(&mut self) -> AdminResult<()> {
        tracing::info!("停止RustCloud管理框架");
        
        // 停止HTTP服务器
        if let Some(handle) = self.server_handle.take() {
            handle.abort();
        }

        // 停止所有注册的组件
        {
            let components = self.components.read().await;
            for (name, component) in components.iter() {
                match component.stop().await {
                    Ok(_) => tracing::info!("组件停止成功: {}", name),
                    Err(e) => tracing::error!("组件停止失败: {} - {}", name, e),
                }
            }
        }
        
        Ok(())
    }

    /// 启动HTTP服务器
    async fn start_server(&mut self) -> AdminResult<()> {
        let app = self.create_app().await?;
        let addr = format!("{}:{}", self.config.server.host, self.config.server.port);
        
        let listener = tokio::net::TcpListener::bind(&addr).await
            .map_err(|e| AdminError::api_error(&format!("无法绑定地址 {}: {}", addr, e)))?;
        
        tracing::info!("管理API服务器启动，监听: {}", addr);
        
        let handle = tokio::spawn(async move {
            if let Err(e) = axum::serve(listener, app).await {
                tracing::error!("HTTP服务器运行错误: {}", e);
            }
        });
        
        self.server_handle = Some(handle);
        Ok(())
    }

    /// 创建Web应用
    async fn create_app(&self) -> AdminResult<axum::Router> {
        use axum::{routing::get, Router};
        
        let app = Router::new()
            .route("/", get(|| async { "RustCloud Admin API" }))
            .route("/health", get(api::health_check))
            .route("/api/v1/components", get(api::list_components))
            .route("/api/v1/system/info", get(api::system_info))
            // 更多路由将在各个子模块中定义
            .layer(tower_http::trace::TraceLayer::new_for_http())
            .layer(tower_http::cors::CorsLayer::permissive());
            
        Ok(app)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_admin_framework_creation() {
        let config = AdminConfig::default();
        let framework = AdminFramework::new(config);
        
        let components = framework.list_components().await;
        assert_eq!(components.len(), 0);
    }

    #[test]
    fn test_admin_error_creation() {
        let error = AdminError::api_error("测试错误");
        assert!(matches!(error, AdminError::ApiError(_)));
        
        let error = AdminError::auth_error("认证失败");
        assert!(matches!(error, AdminError::AuthError(_)));
    }

    #[test]
    fn test_component_status() {
        let status = ComponentStatus::Running;
        assert_eq!(status, ComponentStatus::Running);
        
        let error_status = ComponentStatus::Error("测试错误".to_string());
        assert!(matches!(error_status, ComponentStatus::Error(_)));
    }

    #[test]
    fn test_admin_config_default() {
        let config = AdminConfig::default();
        assert_eq!(config.server.port, 8080);
        assert!(config.auth.enabled);
        assert!(config.audit.enabled);
        assert!(config.diagnostics.enabled);
    }
}